home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Games / Game Sample Code / ZAM 1.0a13 / GameSource / pixiZAM - direct blitter / pixiZAM.c next >
Encoding:
C/C++ Source or Header  |  1993-09-16  |  6.1 KB  |  233 lines  |  [TEXT/KAHL]

  1. #include "PixiZAM.h"
  2.  
  3.  
  4. OSErr LoadPixiFromCIcon(pixiZAM *pz, short resID)
  5. /*
  6.     Load the icons into a GWorld, then copy from the GWorld
  7.     to the pixiZAM.
  8.     
  9.     Need to:  Either read the icon data directly from the iconHandle (GetResource)
  10.                 or fix the crappy GWOrld extra rowLong problem for real.
  11.                 
  12. */
  13. {
  14.     CIconHandle    cicn;                // the icon we are loading
  15.     GWorldPtr    image;                // the image of the icon
  16.     GWorldPtr    mask;                // the mask that defines it
  17.     long        imageSize;            // number of bytes for the image
  18.     char        *pixBaseAddr;        // base address of pixmap in GWORld
  19.     OSErr        err = noErr;        // 
  20.     char        *maskFixer;            // used to make sure the mask is correct
  21.     Rect        alignedBounds;        // rect stretched to be long aligned
  22.     short        realRowBytes;        // this will one day be the real rowBytes, no padding
  23.     short        needDump = 0;        // bit flags set here to manage memory
  24.  
  25.     enum     {     kDumpCicn = 1,             // if any of these flags are set
  26.                 kDumpImageGWorld = 2,     // the object they represent will
  27.                 kDumpMaskGWorld = 4,     // be disposed of at the end of the function
  28.                 kDumpImageZAM = 8        // in the case of an error, if any of the
  29.             };                            // pixiZAM has been allocated, it will be dumped
  30.     
  31.     /*
  32.         first load in the color icon
  33.     */
  34.     cicn = GetCIcon(resID);
  35.     if(!cicn) {
  36.         err = ResError();
  37.         ErrMsgCode("\pErrror  GetCIcon",err);
  38.     }
  39.     
  40.     /* now create a GWorld from it, and set the bit to dump it. */
  41.     if(err == noErr) {
  42.         needDump |= kDumpCicn;
  43.         err = CreateGWorldFromCIcon(&image, cicn);
  44.         if(err != noErr) {
  45.             ErrMsgCode("\pError creating GWorld for image",err);
  46.         }
  47.     }
  48.     
  49.     /* if that was cool, we do the same thing for the mask */
  50.     if(err == noErr) {
  51.         needDump |= kDumpImageGWorld;
  52.         err = CreateGWorldFromCIconMask(&mask, cicn);
  53.         if(err != noErr) {
  54.             ErrMsgCode("\pError creating GWorld",err);
  55.         }
  56.     }
  57.     
  58.     /* we now do not need the icon anymore */
  59.     if( (needDump & kDumpCicn) != 0)
  60.         DisposCIcon(cicn);
  61.     
  62.     /* Calculate the needed memory for the pixiZAM image, and get it */
  63.     if(err == noErr) {
  64.         needDump |= kDumpMaskGWorld;
  65.  
  66.         //realRowBytes = (image->portRect.right - image->portRect.left);        
  67.         realRowBytes = 0x7FFF & (**image->portPixMap).rowBytes;        
  68.         alignedBounds = image->portRect;
  69.         LongAlignRect(&alignedBounds);
  70.  
  71.         imageSize = (alignedBounds.bottom 
  72.                     - alignedBounds.top)
  73.                     * realRowBytes;
  74.  
  75.         if (imageSize & 3)    {
  76.             imageSize &= ~3;
  77.             imageSize += 4;
  78.         }
  79.  
  80.         pz->image = (long*)NewPtrClear(imageSize);
  81.         if(!pz->image) {
  82.             err = MemError();
  83.             ErrMsgCode("\pError allocating pz->image",err);
  84.         }
  85.     }
  86.     
  87.     /* get the same amount of memory for the mask */
  88.     if(err == noErr) {
  89.         pz->mask = (long*)NewPtrClear(imageSize);
  90.         if(!pz->mask) {
  91.             err = MemError();
  92.             ErrMsgCode("\pError allocating pz->mask",err);
  93.             needDump |= kDumpImageZAM;
  94.         }
  95.     }
  96.     
  97.     /* now load the GWorlds into the pixiZAM buffers */
  98.     
  99.     if(err == noErr) {
  100.         
  101.         LockPixels(image);
  102.         pixBaseAddr = GetPixBaseAddr(GetGWorldPixMap(image));
  103.         BlockMove(pixBaseAddr, pz->image, imageSize);
  104.         UnlockPixels(image);
  105.         
  106.         LockPixels(mask);
  107.         pixBaseAddr = GetPixBaseAddr(GetGWorldPixMap(mask));        
  108.         BlockMove(pixBaseAddr, pz->mask, imageSize);
  109.         UnlockPixels(mask);
  110.          
  111.          /* this makes any byte of the mask that has on pixels */
  112.          /* all the way turned on, just to make sure the mask color */
  113.          /* indexes are correct */
  114.         maskFixer = (char*)pz->mask;
  115.         while(imageSize--) {
  116.             if(*maskFixer)    
  117.                 *maskFixer = 0xFF;
  118.             *maskFixer++;
  119.         }
  120.  
  121.         /* initialize the rest of the pixiZAM structure */
  122.         pz->bounds = image->portRect;
  123.         pz->height = image->portRect.bottom - image->portRect.top;
  124.         pz->rowLongs = (realRowBytes/ 4);
  125.     }
  126.     
  127.     /* check the bits in needDump, and clean up what we allocated */
  128.     
  129.     if(needDump & kDumpImageGWorld)
  130.         DisposeGWorld(image);
  131.         
  132.     if(needDump & kDumpMaskGWorld)
  133.         DisposeGWorld(mask);
  134.  
  135.     if( needDump & kDumpImageZAM)
  136.         DisposePtr(image);                // only if allocated and an error occured
  137.  
  138.     return err;
  139. }
  140.  
  141. void PixelMover(pixiZAM *srcPixi, PixMapHandle destMap, Rect *destRect)
  142. /*
  143.     This is a non-masked straight copy.
  144.     
  145.     The entire source is copied to the topLeft of the destination rectangle
  146.     
  147.     Assumes:  The destination's color table matches the pixiZAMs
  148.               The pixiZAM is 8 bits deep, and so is the destination
  149. */
  150. {
  151.     register long *dst;
  152.     register long *src;
  153.     register long *mask;
  154.     register long numRowsToCopy;
  155.     register long rowLongsOffset;
  156.     register long stripRowBytes;
  157.              char mmuMode;
  158.  
  159.     stripRowBytes = (0x7FFF & (**destMap).rowBytes);
  160.     
  161.     src = srcPixi->image;
  162.     mask = srcPixi->mask;
  163.  
  164.     LongAlignRect(destRect);
  165.     
  166.     dst = (long *)(GetPixBaseAddr(destMap) + (stripRowBytes * destRect->top) + destRect->left);
  167.     
  168.     mmuMode = true32b;
  169.     SwapMMUMode(&mmuMode);
  170.     
  171.     numRowsToCopy = srcPixi->height;
  172.     rowLongsOffset = (stripRowBytes/4) - srcPixi->rowLongs;
  173.     
  174.     while(numRowsToCopy--) {
  175.  
  176.         switch(srcPixi->rowLongs) {
  177.             #include "pmSplat.gen"
  178.         }
  179.         dst += rowLongsOffset;
  180.     }
  181.     
  182.     SwapMMUMode(&mmuMode);
  183. }
  184.  
  185. void MaskedPixelMover(pixiZAM *srcPixi, PixMapHandle destMap, Rect *destRect)
  186. /*
  187.     This is a masked copy.
  188.     
  189.     The entire source is copied to the topLeft of the destination rectangle
  190.     
  191.     Assumes:  The destination's color table matches the pixiZAMs
  192.               The pixiZAM is 8 bits deep, and so is the destination
  193.               Also assumes that clipping won't be needed, so don't tell this
  194.               to do anything stupid, cause it will.
  195.               
  196.     NeedTo:   Correct problems in the pixiZam loaded because the images contain
  197.               an extra longword at the end of each row, inherited from the GWorld.
  198.     
  199.     Also NeedTo:  Write one that take a source and destination rectangle
  200. */
  201. {
  202.     register long *dst;
  203.     register long *src;
  204.     register long *mask;
  205.     register long numRowsToCopy;
  206.     register long rowLongsOffset;
  207.     register long stripRowBytes;
  208.              char mmuMode;
  209.  
  210.     stripRowBytes = (0x7FFF & (**destMap).rowBytes);
  211.     
  212.     src = srcPixi->image;
  213.     mask = srcPixi->mask;
  214.     
  215.     LongAlignRect(destRect);
  216.     
  217.     dst = (long *)(GetPixBaseAddr(destMap) + (stripRowBytes * destRect->top) + destRect->left);
  218.     
  219.     mmuMode = true32b;
  220.     SwapMMUMode(&mmuMode);
  221.     
  222.     numRowsToCopy = srcPixi->height;
  223.     rowLongsOffset = (stripRowBytes/4) - srcPixi->rowLongs;
  224.         
  225.     while(numRowsToCopy--) {
  226.         switch(srcPixi->rowLongs) {
  227.             #include "pmSplatMask.gen"
  228.         }
  229.         dst += rowLongsOffset;
  230.     }
  231.     
  232.     SwapMMUMode(&mmuMode);
  233. }